package com.chatplus.application.listener.order;

import com.chatplus.application.common.constant.RedisPrefix;
import com.chatplus.application.common.lock.TLock;
import com.chatplus.application.common.lock.TurnRightLock;
import com.chatplus.application.common.logging.SouthernQuietLogger;
import com.chatplus.application.common.logging.SouthernQuietLoggerFactory;
import com.chatplus.application.common.util.PlusJsonUtils;
import com.chatplus.application.domain.entity.orders.OrderEntity;
import com.chatplus.application.enumeration.OrderStatusEnum;
import com.chatplus.application.event.GenericEvent;
import com.chatplus.application.event.order.OrderUpdateEvent;
import com.chatplus.application.event.order.dto.OrderRequestEvent;
import com.chatplus.application.service.account.UserProductLogService;
import com.chatplus.application.service.orders.OrderService;
import org.redisson.api.RedissonClient;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

/**
 * 订单事件监听
 *
 * @author chj
 * @date 2024/2/6
 **/
@Component
public class OrderEventListener {
    private static final SouthernQuietLogger LOGGER = SouthernQuietLoggerFactory.getLogger(OrderEventListener.class);

    private final OrderService orderService;
    private final RedissonClient redissonClient;
    private final UserProductLogService userProductLogService;
    private final TurnRightLock turnRightLock;

    public OrderEventListener(OrderService orderService, RedissonClient redissonClient, UserProductLogService userProductLogService, TurnRightLock turnRightLock) {
        this.orderService = orderService;
        this.redissonClient = redissonClient;
        this.userProductLogService = userProductLogService;
        this.turnRightLock = turnRightLock;
    }

    @EventListener(classes = OrderUpdateEvent.class)
    @Async
    @Transactional(rollbackFor = Exception.class)
    public void paySuccessEventListener(GenericEvent<OrderRequestEvent> event) {
        LOGGER.message("收到订单更新事件").context("data", PlusJsonUtils.toJsonString(event)).info();
        OrderRequestEvent orderRequestEvent = event.getData();
        if (orderRequestEvent == null) {
            return;
        }
        OrderStatusEnum status = orderRequestEvent.getStatus();
        Long orderId = orderRequestEvent.getOrderId();
        //加锁
        String lockKey = "Key:Lock:OrderEventListener:" + orderId;
        try (TLock tLock = turnRightLock.tryLock(lockKey)) {
            if (tLock == null) {
                return;
            }
            OrderEntity orderEntity = orderService.getById(orderId);
            if (orderEntity == null || orderEntity.getStatus() == status) {
                return;
            }
            orderEntity.setStatus(status);
            orderEntity.setTradeNo(orderRequestEvent.getTradeTransactionId());
            orderEntity.setPayTime(orderRequestEvent.getSuccessAt());
            orderService.updateById(orderEntity);
            // 给用户新增对应的套餐
            if (status == OrderStatusEnum.SUCCESS) {
                userProductLogService.addProductToUser(orderEntity.getUserId(), orderEntity.getProductId(), orderEntity.getId());
            }
            // 清空缓存
            redissonClient.getBucket(RedisPrefix.PAY_STATUS_PREFIX + orderEntity.getId()).deleteAsync();
        } catch (Exception e) {
            LOGGER.message("订单更新事件异常")
                    .context("data", PlusJsonUtils.toJsonString(event))
                    .exception(e)
                    .error();
        }

    }
}
